package com.heima.comment.service.impl;

import com.heima.comment.feign.UserFeign;
import com.heima.comment.service.CommentRepayService;
import com.heima.common.aliyun.GreeTextScan;
import com.heima.model.comment.dtos.CommentRepayDto;
import com.heima.model.comment.dtos.CommentRepayLikeDto;
import com.heima.model.comment.dtos.CommentRepaySaveDto;
import com.heima.model.comment.pojos.ApComment;
import com.heima.model.comment.pojos.ApCommentRepay;
import com.heima.model.comment.pojos.ApCommentRepayLike;
import com.heima.model.comment.vo.ApCommentRepayVo;
import com.heima.model.common.dtos.ResponseResult;
import com.heima.model.common.enums.AppHttpCodeEnum;
import com.heima.model.user.pojos.ApUser;
import com.heima.search.utils.threadlocal.AppThreadLocalUtils;
import lombok.extern.slf4j.Slf4j;
import org.redisson.api.RLock;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.Sort;
import org.springframework.data.mongodb.core.MongoTemplate;
import org.springframework.data.mongodb.core.query.Criteria;
import org.springframework.data.mongodb.core.query.Query;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;
@Service
@Slf4j
public class CommentRepayServiceImpl implements CommentRepayService {
    @Autowired
    private MongoTemplate mongoTemplate;
    @Autowired
    private UserFeign userFeign;
    @Autowired
    private GreeTextScan greeTextScan;
    @Resource(name="likesLock")
    RLock rLock;
    @Override
    public ResponseResult loadCommentRepay(CommentRepayDto dto) {


        //检查参数
        if (dto == null || dto.getCommentId() == null) {
            return ResponseResult.errorResult(AppHttpCodeEnum.PARAM_REQUIRE);
        }
        if (dto.getMinDate() == null) {
            dto.setMinDate(new Date());
        }
        ApUser user = AppThreadLocalUtils.getUser();
        Query query = Query.query(Criteria.where("commentId").is(dto.getCommentId()).and("createdTime").lt(dto.getMinDate())
        ).with(Sort.by(Sort.Direction.DESC, "createdTime")).limit(20);

        List<ApCommentRepay> apCommentRepays = mongoTemplate.find(query, ApCommentRepay.class);
        if (user == null) {
            return ResponseResult.okResult(apCommentRepays);
        }
        List<String> ids = apCommentRepays.stream().map(ApCommentRepay::getId).collect(Collectors.toList());
        Query queryLikes = Query.query(Criteria.where("authorId").is(user.getId()).and("commentRepayId").in(ids));
        List<ApCommentRepayLike> apCommentRepayLikes = mongoTemplate.find(queryLikes, ApCommentRepayLike.class);
        List<String> collect = apCommentRepayLikes.stream().map(ApCommentRepayLike::getCommentRepayId).collect(Collectors.toList());
        List<ApCommentRepayVo> apCommentRepayVos = apCommentRepays.stream().map(apCommentRepay -> {
            ApCommentRepayVo apCommentRepayVo = new ApCommentRepayVo();
            BeanUtils.copyProperties(apCommentRepay, apCommentRepayVo);
            if (collect.contains(apCommentRepay.getId())) {
                apCommentRepayVo.setOperation((short) 0);
            }
            return apCommentRepayVo;
        }).collect(Collectors.toList());
        return ResponseResult.okResult(apCommentRepayVos);
    }

    @Override
    public ResponseResult saveCommentRepay(CommentRepaySaveDto dto) {
        //判断参数
        if (dto == null || dto.getCommentId() == null) {
            return ResponseResult.errorResult(AppHttpCodeEnum.PARAM_REQUIRE);
        }
        if (dto.getContent() == null || dto.getContent().length() > 140) {
            return ResponseResult.errorResult(AppHttpCodeEnum.PARAM_INVALID);
        }
        ApUser user = AppThreadLocalUtils.getUser();

        if (user == null) {
            return ResponseResult.errorResult(AppHttpCodeEnum.NEED_LOGIN);
        }
        ApComment apComment = mongoTemplate.findById(dto.getCommentId(), ApComment.class);
        if (apComment == null) {
            return ResponseResult.errorResult(AppHttpCodeEnum.DATA_NOT_EXIST, "评论不存在");
        }
        try {
            Map map = greeTextScan.greeTextScan(dto.getContent());
            String suggestion = (String) map.get("suggestion");
            if ("block".equals(suggestion)) {
                return ResponseResult.errorResult(AppHttpCodeEnum.PARAM_INVALID, "评论有违规，请注意你的言辞");
            }
        } catch (Exception e) {
            e.printStackTrace();
            return ResponseResult.errorResult(AppHttpCodeEnum.SERVER_ERROR);
        }
        ApCommentRepay apCommentRepay = new ApCommentRepay();
        apCommentRepay.setAuthorId(user.getId());
        apCommentRepay.setAuthorName(user.getName());
        apCommentRepay.setCommentId(dto.getCommentId());
        apCommentRepay.setContent(dto.getContent());
        apCommentRepay.setLikes(0);
        apCommentRepay.setCreatedTime(new Date());
        apCommentRepay.setUpdatedTime(new Date());
        mongoTemplate.save(apCommentRepay);
        apComment.setReply(apComment.getReply() + 1);
        mongoTemplate.save(apComment);


        return ResponseResult.okResult(AppHttpCodeEnum.SUCCESS);
    }

    @Override
    public ResponseResult saveCommentRepayLike(CommentRepayLikeDto dto) {
        //判断参数
        if (dto == null || dto.getCommentRepayId() == null) {
            return ResponseResult.errorResult(AppHttpCodeEnum.PARAM_REQUIRE);

        }
        if (dto.getOperation() == null || (dto.getOperation() != 0 && dto.getOperation() != 1)) {
            return ResponseResult.errorResult(AppHttpCodeEnum.PARAM_REQUIRE);
        }
        ApUser user = AppThreadLocalUtils.getUser();
        if (user == null) {
            return ResponseResult.errorResult(AppHttpCodeEnum.NEED_LOGIN);
        }
        rLock.lock();
        ApCommentRepay repay;
        try {
            repay = mongoTemplate.findById(dto.getCommentRepayId(), ApCommentRepay.class);
            if (repay == null) {
                return ResponseResult.errorResult(AppHttpCodeEnum.DATA_NOT_EXIST, "该回复不存在");
            }
            if (dto.getOperation() == 0) {
                repay.setLikes(repay.getLikes() + 1);
                mongoTemplate.save(repay);
                ApCommentRepayLike apCommentRepayLike = new ApCommentRepayLike();
                apCommentRepayLike.setAuthorId(user.getId());
                apCommentRepayLike.setCommentRepayId(dto.getCommentRepayId());
                apCommentRepayLike.setOperation((short) 0);
                mongoTemplate.save(apCommentRepayLike);

            }
            if (dto.getOperation() == 1) {
                repay.setLikes(repay.getLikes() == 0 ? 0 : repay.getLikes() - 1);
                mongoTemplate.save(repay);
                Query query = Query.query(Criteria.where("authorId").is(user.getId()).and("commentRepayId").is(dto.getCommentRepayId()));
                mongoTemplate.remove(query,ApCommentRepayLike.class);

            }
        } finally {
            rLock.unlock();
        }
        Map map = new HashMap();
        map.put("likes",repay.getLikes());
        return ResponseResult.okResult(map);
    }
}
